﻿using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Windows;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Media3D;
using AIStudio.Wpf.DiagramDesigner.Models;

namespace AIStudio.Wpf.DiagramDesigner
{
    public class DrawingDesignerItemViewModelBase : DesignerItemViewModelBase
    {
        public DrawingDesignerItemViewModelBase() : base()
        {

        }

        public DrawingDesignerItemViewModelBase(IDiagramViewModel root, DrawMode drawMode, Point startPoint, ColorViewModel colorViewModel, bool erasable) : this(root, drawMode, new List<Point> { startPoint }, colorViewModel, erasable, false)
        {

        }

        public DrawingDesignerItemViewModelBase(IDiagramViewModel root, DrawMode drawMode, List<Point> points, ColorViewModel colorViewModel, bool erasable, bool isFinish = true) : base(root)
        {
            DrawMode = drawMode;
            Points = points;
            Erasable = erasable;
            IsFinish = isFinish;
            if (colorViewModel != null)
                ColorViewModel = colorViewModel;
            InitNewDrawing();
        }

        public DrawingDesignerItemViewModelBase(IDiagramViewModel root, SelectableItemBase designer) : base(root, designer)
        {

        }

        public DrawingDesignerItemViewModelBase(IDiagramViewModel root, SerializableItem serializableItem, string serializableType) : base(root, serializableItem, serializableType)
        {

        }

        public override SelectableItemBase GetSerializableObject()
        {
            return new DrawingDesignerItemBase(this);
        }

        protected override void Init(IDiagramViewModel root, bool initNew)
        {
            base.Init(root, initNew);
        }

        protected override void InitNew()
        {
            ClearConnectors();
        }

        protected virtual void InitNewDrawing()
        {
            if (IsFinish)
            {
                OnMouseUp(null, null);
                this.SelectedDisable = Erasable;
            }
            else if (Erasable)
            {
                if (Root?.DrawModeViewModel != null)
                {
                    this.ColorViewModel = CopyHelper.Mapper(Root.DrawModeViewModel.DrawingColorViewModel);
                }
                else
                {
                    this.ColorViewModel = CopyHelper.Mapper(_service.DrawModeViewModel.DrawingColorViewModel);
                }
            }
        }

        protected override void LoadDesignerItemViewModel(SelectableItemBase designerbase)
        {
            base.LoadDesignerItemViewModel(designerbase);

            if (designerbase is DrawingDesignerItemBase designer)
            {
                this.Erasable = designer.Erasable;
                this.Geometry = PathGeometry.CreateFromGeometry(Geometry.Parse(designer.Geometry));
                if (!string.IsNullOrEmpty(designer.Matrix))
                {
                    this.Geometry.Transform = Transform.Parse(designer.Matrix);
                }
                this.Points = designer.Points;
                this.DrawMode = designer.DrawMode;
                this.SelectedDisable = Erasable;
            }
        }

        public virtual bool OnMouseMove(IInputElement sender, MouseEventArgs e)
        {
            return true;
        }

        public virtual bool OnMouseDown(IInputElement sender, MouseButtonEventArgs e)
        {
            return true;
        }

        public virtual bool OnMouseUp(IInputElement sender, MouseButtonEventArgs e)
        {
            if (IsFinish)
            {
                IsLoaded = false;
                if (Geometry != null)
                {
                    var left = Geometry.Bounds.Left;
                    var top = Geometry.Bounds.Top;
                    if (Geometry.Transform is TransformGroup transformGroup)
                    {
                        TranslateTransform translateTransform = transformGroup.Children.OfType<TranslateTransform>().FirstOrDefault();
                        transformGroup.Children.Remove(translateTransform);
                        transformGroup.Children.Add(new TranslateTransform(0 - Geometry.Bounds.Left, 0 - Geometry.Bounds.Top));
                    }
                    else
                    {
                        transformGroup = new TransformGroup();
                        transformGroup.Children.Add(new TranslateTransform(0 - Geometry.Bounds.Left, 0 - Geometry.Bounds.Top));
                        Geometry.Transform = transformGroup;
                    }

                    if (Erasable)
                    {
                        var aPen = new Pen(ColorViewModel.LineColor.ToBrush(), ColorViewModel.LineWidth);
                        aPen.DashStyle = new DashStyle(StrokeDashArray.Dash[(int)ColorViewModel.LineDashStyle], 1);
                        Geometry = Geometry.GetWidenedPathGeometry(aPen); //可擦除，需要把Geometry转成几何图像，所以不能有填充色

                    }
                    UpdateLocation(new Point(left, top));
                }
                IsLoaded = true;
            }
            return true;
        }

        public virtual bool Erase(Geometry erase)
        {
            if (Erasable && Keyboard.IsKeyDown(Key.LeftShift) == false)
            {
                erase.Transform = new TranslateTransform(0 - Left, 0 - Top);
                Geometry = Geometry.Combine(Geometry, erase, GeometryCombineMode.Exclude, null);

                if (Geometry.IsEmpty())
                    return true;
            }
            else
            {
                if (this.GetBounds().IntersectsWith(erase.Bounds))//相交
                {
                    return true;
                }
            }
            return false;
        }

        public bool Erasable
        {
            get; set;
        }

        private Geometry _geometry;
        public Geometry Geometry
        {
            get
            {
                return _geometry;
            }
            set
            {
                SetProperty(ref _geometry, value);
            }
        }

        public bool IsFinish
        {
            get; set;
        }

        private List<Point> _points;
        public List<Point> Points
        {
            get
            {
                return _points;
            }
            set
            {
                SetProperty(ref _points, value);
            }
        }

        public DrawMode DrawMode
        {
            get; set;
        }

        #region 属性改变
        protected override void Item_PropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            if (IsLoaded == false) return;

            switch (e.PropertyName)
            {
                case nameof(ItemWidth):
                case nameof(ItemHeight):
                    {

                        UpdateTransform();
                        break;
                    }
            }
        }
        #endregion

        public override void RemoveFromSelection()
        {
            if (Erasable == true)
            {
                this.SelectedDisable = true;
            }
            base.RemoveFromSelection();
        }

        public override void AddToSelection(bool selected, bool clearother)
        {
            if (selected == true && _service.DrawModeViewModel.DrawingDrawMode == DrawMode.Select)
            {
                this.SelectedDisable = false;
            }
            base.AddToSelection(selected, clearother);
        }

        protected virtual void UpdateLocation(Point point)
        {
            if (Erasable)
            {
                ItemWidth = Geometry.Bounds.Width;// - ColorViewModel.LineWidth * 0.5;
                ItemHeight = Geometry.Bounds.Height;// - ColorViewModel.LineWidth * 0.5;
                Left = point.X;
                Top = point.Y;
            }
            else
            {
                ItemWidth = Geometry.Bounds.Width;// + ColorViewModel.LineWidth * 0.5;
                ItemHeight = Geometry.Bounds.Height;// + ColorViewModel.LineWidth * 0.5;
                Left = point.X;
                Top = point.Y;
            }
        }

        protected void UpdateTransform()
        {
            if (Geometry.Transform is TransformGroup transformGroup)
            {
            }
            else
            {
                transformGroup = new TransformGroup();
                Geometry.Transform = transformGroup;
            }

            ScaleTransform scaleTransform = transformGroup.Children.OfType<ScaleTransform>().FirstOrDefault();
            transformGroup.Children.Remove(scaleTransform); ;

            double radiox = ItemWidth / Geometry.Bounds.Width;
            double radioy = ItemHeight / Geometry.Bounds.Height;
            transformGroup.Children.Add(new ScaleTransform(radiox, radioy));
        }

    }
}
